package util.jdbc;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

/**
 * 自定义连接池，getInstance(),返回Pool的唯一实例，第一次调用时执行构造函数
 * 构造函数Pool()调用驱动装载LoadDrivers()函数，
 * 注意：加载资源配置文件时路径的写法
 */
public abstract  class Pool {
    private static Logger logger = LoggerFactory.getLogger(Pool.class);
    public String propertiesName = "/jdbc.properties";
    private static Pool instance = null; //定义唯一实例
    protected  int maxConnect = 100; //最大连接数
    protected int normalConnect = 10; //保持连接数
    protected String driverName = null; //驱动
    protected Driver driver = null; //驱动变量

    //私有的构造函数，不允许外界访问
    protected Pool(){
        try {
            init();
            loadDrivers(driverName);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //初始化所有从配置文件中读取的成员变量
    private void init() throws IOException {
        InputStream is = Pool.class.getResourceAsStream(propertiesName);
        Properties p = new Properties();
        p.load(is);
        this.driverName = p.getProperty("jdbc.driver");
        this.maxConnect = Integer.parseInt(p.getProperty("maxConnect"));
        this.normalConnect = Integer.parseInt(p.getProperty("normalConnect"));
    }

    //装载和注册所有的JDBC驱动程序
    protected  void loadDrivers(String dri){
        String driverName = dri;
        try {
            driver = (Driver) Class.forName(driverName).newInstance();
            DriverManager.registerDriver(driver);
            logger.info("成功注册JDBC程序===>: "  + driverName);
        }catch (Exception e){
            logger.error("无法注册JDBC程序===>: " +driverName + ",错误" + e);
        }
    }

    //创建连接池
    public abstract  void createPool();

    /**
     * 单例模式
     * @return
     * @throws IOException
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws ClassNotFoundException
     */
    public static synchronized Pool getInstance() throws IOException,InstantiationException,IllegalAccessException,ClassNotFoundException{
        if(instance == null){
            instance = (Pool)Class.forName("util.Pool").newInstance();
        }
        return  instance;
    }

    //或得一个可用连接，如果没有则创建一个连接
    public abstract Connection getConnection();
    //或得一个连接，有时间限制
    public abstract Connection getConnection(Long time);
    //将连接对象返回给连接池
    public abstract  void freeConnection(Connection connection);
    //返回当前空闲的连接数
    public abstract  int getNum();
    //返回当前工作的连接数
    public abstract  int getNumActive();

    /**
     * 释放jdbc驱动
     */
    protected synchronized void release(){
        try {
            DriverManager.deregisterDriver(driver);
           logger.info("撤销JDBC驱动程序===>: " + driverName.getClass().getName());
        }catch (SQLException e){
            logger.error("无法撤销jdbc驱动程序的注册===>: " + driverName.getClass().getName());
        }
    }
}
